/********************************************************************************
*                                                                               *
* kWookaProjectInfo.hpp -- The data struct definition                           *
*                                                                               *
* Copyright (c) Fengren Technology(Guangzhou) Co.LTD. All rights reserved.      *
*                                                                               *
********************************************************************************/


#ifndef kWookaProjectInfo_hpp
#define kWookaProjectInfo_hpp

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include <wx/wx.h>
    #include <wx/dialog.h>
#else
    #include <wx/wxprec.h>
#endif
#include <wx/dynarray.h>
#include "cJSON.h"

class kWookaProcessExecutor;
class kWookaProjectInfo;
class kWookaAppItemInfo;

WX_DECLARE_STRING_HASH_MAP(kWookaProcessExecutor*, kWookaExecutorMap);

class kWookaProcessPerformanceInfo: public wxObject {
public:
    wxString timestamp;         // Timestamp lable
    double cpuUsages;           // cpu usage percent
    size_t memoryUsed;          // memory usage MB
    ULONG64 diskReadSpeed;       // disk io speed for read
    ULONG64 diskWriteSpeed;      // disk io speed for write
    ULONG64 networkRecvSpeed;    // network io speed for recv
    ULONG64 networkSendSpeed;    // network io speed for send
    long   threads;             // threads
    long   handlers;            // handlers
    bool   success;             // success or not

    kWookaProcessPerformanceInfo() {
        cpuUsages = 0;
        memoryUsed = 0;
        diskReadSpeed = 0;
        diskWriteSpeed = 0;
        networkSendSpeed = 0;
        networkRecvSpeed = 0;
        threads = 0;
        handlers = 0;
        success = false;
    }

    virtual ~kWookaProcessPerformanceInfo() {
        //wxLogDebug(wxT("kWookaProcessPerformanceInfo destroyed."));
    }

public:
    kWookaProcessPerformanceInfo* Clone() {
        kWookaProcessPerformanceInfo* p = new kWookaProcessPerformanceInfo();
        p->timestamp = this->timestamp;
        p->cpuUsages = this->cpuUsages;
        p->memoryUsed = this->memoryUsed;
        p->diskReadSpeed = this->diskReadSpeed;
        p->diskWriteSpeed = this->diskWriteSpeed;
        p->networkSendSpeed = this->networkSendSpeed;
        p->networkRecvSpeed = this->networkRecvSpeed;
        p->threads = this->threads;
        p->handlers = this->handlers;
        p->success = this->success;
        return p;
    }
};

class kWookaProjectRuntimeInfo {
public:
    kWookaProjectRuntimeInfo(kWookaProjectInfo* proj) {
        m_project = proj;
    }

    ~kWookaProjectRuntimeInfo() {
        executeMap.clear();
        wxLogDebug(wxT("kWookaProjectRuntimeInfo destroyed."));
    }
public:
    kWookaProcessExecutor* GetExecutor(const wxString& app);
    wxVector<kWookaProcessExecutor*> GetAllExecutors();
    bool IsRunning();
    void Clear();

protected:
    kWookaProcessExecutor* CreateExecutor(kWookaAppItemInfo* appItem);

private:
    kWookaProjectInfo* m_project;
    kWookaExecutorMap executeMap;
};


class kWookaJvmConfigInfo
{
public:
    wxString jvmHeap;
    wxString jvmMaxHeap;
    wxString jvmMaxPermSize;
    wxString jvmMaxDirectMemorySize;
    wxString jvmGCOptions;
    wxString jvmOtherOptions;
    wxString jdkHome;
    wxString jvmDebugAddress;
    bool     jvmDebugEnabled;
};

class kWookaAppConfigItemInfo {
public:
    wxString configKey;
    wxString configValue;
    wxString configType;
};

class kWookaMavenRepoInfo {
public:
    wxString repoId;
    wxString snapshot;
    wxString address;
};

WX_DECLARE_OBJARRAY(kWookaAppConfigItemInfo, kWookaAppConfigArray);
WX_DECLARE_OBJARRAY(kWookaMavenRepoInfo, kWookaMavenRepoArray);

class kWookaAppItemInfo
{
public:
    kWookaAppItemInfo() {
        sort = 0;
    }
    ~kWookaAppItemInfo() {
        appConfigs.Clear();
    }
public:
    wxString id;
    wxString name;
    wxString description;
    wxString source;
    wxString version;
    wxString groupId;
    wxString startClass;
    wxString appType;
    int      sort;
    wxArrayString libraries;

    kWookaJvmConfigInfo jvmConfig;
    kWookaAppConfigArray appConfigs;
    

    void UpdateItem(const wxString& key, const wxString& value, const wxString& type = wxT(""));

    bool ItemExist(const wxString& key);

    void AddLibrary(const wxString& lib);
    void DelLibrary(const wxString& lib);

    const wxString& GetItemValue(const wxString& key);

    static const wxString DEFAULT_EMPTY_STRING;
public:
    cJSON* toJSONObject();
    void fromJSONObject(cJSON* json);
};

WX_DECLARE_OBJARRAY(kWookaAppItemInfo, kWookaAppArray);

class kWookaProjectInfo
{
public:
    kWookaProjectInfo () {
        runtime = new kWookaProjectRuntimeInfo(this);
        m_maxOrder = 0;
        Applications.Clear();
    }

    ~kWookaProjectInfo() {
        if (runtime != NULL) {
            runtime->Clear();
            delete runtime;
        }
    }

    /*
    * Doing shutdown for this project
    */
    void Shutdown() {
        if (runtime != NULL) {
            runtime->Clear();
            delete runtime;
            runtime = NULL;
        }
    }

    wxString workspace;
    wxString timestamp;
    wxString mavenHome;
    kWookaJvmConfigInfo jvmConfig;
    kWookaAppConfigArray appConfigs;    
    kWookaAppArray Applications;
    kWookaMavenRepoArray mavenRepositories;
    kWookaProjectRuntimeInfo* runtime;
    int m_maxOrder;

protected:
    void fromJSON(cJSON* json);

public:
    void AddAppItem(kWookaAppItemInfo& appItem)  {
        if (appItem.sort == 0) {
            appItem.sort = m_maxOrder ++;
        }
        else {
            m_maxOrder = m_maxOrder < appItem.sort ? appItem.sort + 1: m_maxOrder + 1;
        }
        Applications.Add(appItem);
    }

    void DeleteAppItem(const kWookaAppItemInfo* appItem) {
        DeleteAppItem(appItem->source);
    }

    void DeleteAppItem(const wxString& source) {
        for (size_t s = 0; s < Applications.Count(); s ++) {
            if (Applications[s].source == source) {
                Applications.RemoveAt(s);
            }
        }
    }

    kWookaAppItemInfo* GetAppItem(const wxString& source) {
        for (size_t s = 0; s < Applications.Count(); s++) {
            kWookaAppItemInfo& it = Applications.Item(s);
            if (source == it.source) {
                return Applications.Detach(s);
            }
        }
        return NULL;
    }

    virtual void Save(const wxString& path);
    virtual void Load(const wxString& path);
};


#endif /* kWookaProjectInfo_hpp */
